/*
 * ExtractiveConcept.java
 *
 * Created on 1 April 2007, 20:15
 *
 */

package rxtokenizer;

/**
 * Class for condition which used during extraction.
 * This class is storaged in ConceptType.
 * @author Ruslan Fayzrakhmanov
 */
public class ExtractiveConcept {

    ExtractiveConcept(ConceptType typeInfo) {
	this.typeInfo = typeInfo;
	this.groupNum = 0;
    }
    
    ExtractiveConcept(ConceptType typeInfo, int groupNum) {
	this.typeInfo = typeInfo;
	this.groupNum = groupNum;
    }
    
	/**
	 * Names of attributes for extraction
	 */
    public static final String VALUE = "value";
    public static final String NUM_VALUE = "numvalue";
    public static final String MIN_VALUE = "minvalue";
    public static final String MAX_VALUE = "maxvalue";
    public static final String LENGTH = "length";
    public static final String MIN_LENGTH = "minlength";
    public static final String MAX_LENGTH = "maxlength";
    public static final String STARTS_WITH = "startswith";
    public static final String ENDS_WITH = "endswith";
    public static final String CONTAINS = "contains";
    
    public static boolean isAttributeExists(String attrName) {
	attrName = attrName.toLowerCase();
	if ( attrName.equals(VALUE)
		|| attrName.equals(NUM_VALUE)
		|| attrName.equals(MIN_VALUE)
		|| attrName.equals(MAX_VALUE)
		|| attrName.equals(LENGTH)
		|| attrName.equals(MIN_LENGTH)
		|| attrName.equals(MAX_LENGTH)
		|| attrName.equals(STARTS_WITH)
		|| attrName.equals(ENDS_WITH)
		|| attrName.equals(CONTAINS)
		)
	return true;
	else return false;
    }
	    
    public static Result checkAttribute(String attrName, String value) {
	attrName = attrName.toLowerCase();
	Result res = Result.NO_ERROR;
	double d=0;
	int i;
	if (attrName.equals(VALUE)
		|| attrName.equals(STARTS_WITH)
		|| attrName.equals(ENDS_WITH)
		|| attrName.equals(CONTAINS))
	    ;
	else if (attrName.equals(NUM_VALUE)) {
	    if (Double.isNaN(d=StringToDouble(value)))
		res = Result.ERROR_11;
	}
	else if (attrName.equals(MIN_VALUE)) {
	    if (Double.isNaN(d=StringToDouble(value)))
		res = Result.ERROR_11;
	}
	else if (attrName.equals(MAX_VALUE)) {
	    if (Double.isNaN(d=StringToDouble(value)))
		res = Result.ERROR_11;
	}
	else if (attrName.equals(LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MIN_LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MAX_LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		;
	    else res = Result.ERROR_11;
	else
	    res = Result.ERROR_12;
	return res;
    }
    
    Result setAttribute(String attrName, String value) {
	attrName = attrName.toLowerCase();
	Result res = Result.NO_ERROR;
	double d;
	int i;
	if (attrName.equals(VALUE))
	    this.value = value;
	else if (attrName.equals(STARTS_WITH))
	    this.startsWith = value;
	else if (attrName.equals(ENDS_WITH))
	    this.endsWith = value;
	else if (attrName.equals(CONTAINS))
	    this.containts = value;
	else if (attrName.equals(NUM_VALUE))
	    if (!Double.isNaN(d=StringToDouble(value)))
		this.numValue = d;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MIN_VALUE))
	    if (!Double.isNaN(d=StringToDouble(value)))
		this.minValue = d;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MAX_VALUE))
	    if (!Double.isNaN(d=StringToDouble(value)))
		this.maxValue = d;
	    else res = Result.ERROR_11;
	else if (attrName.equals(LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		this.length = i;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MIN_LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		this.minLength = i;
	    else res = Result.ERROR_11;
	else if (attrName.equals(MAX_LENGTH))
	    if ((i=StringToInt(value)) >= 0)
		this.maxLength = i;
	    else res = Result.ERROR_11;
	else
	    res = Result.ERROR_12;
	if ((res == Result.NO_ERROR) && (isClear) )
	    isClear = false;
	return res;
    }
    
    private static double StringToDouble(String str) {
	double d;
	try {
	    d = Double.parseDouble(str);
	}
	catch (NumberFormatException ex) {
	    return Double.NaN;
	}
	return d;
    }
    
    private static int StringToInt(String str) {
	int i;
	try {
	    i = Integer.decode(str).intValue();
	}
	catch (NumberFormatException ex) {
	    return -1;
	}
	return i;
    }
    
	/**
	 * Information about concept type
	 */
    private ConceptType typeInfo = null;
    	/**
	 * Number of the group in regular expression
	 */
    private int groupNum = -1;
	/**
	 * Values of attributes for extracting
	 */
    private String value = null;
    private double numValue = Double.NaN;
    private double minValue = Double.NaN;
    private double maxValue = Double.NaN;
    private int length = -1;
    private int minLength = -1;
    private int maxLength = -1;
    private String startsWith = null;
    private String endsWith = null;
    private String containts = null;
    private boolean isClear = true; // true if one of the attributes (typeInfo and groupNum aren't attributes) is set
    
    public boolean isClear() {
	return isClear;
    }
    public ConceptType getTypeInfo () {
	return typeInfo;
    }
    void setTypeInfo (ConceptType typeInfo) {
	this.typeInfo = typeInfo;
    }
    public int getGroupNum () {
	return groupNum;
    }
    void setGroupNum (int groupNum) {
	this.groupNum = groupNum;
    }
    public String getValue () {
	return value;
    }
    void setValue (String value) {
	if (isClear) isClear = false;
	this.value = value;
    }
    public boolean isValueSet() {
	return (value == null)? false: true;
    }
    /*public boolean isEqualValue(String value) {
	return (value.equals(this.value))? true: false;
    }*/
    public double getNumValue () {
	return numValue;
    }
    void setNumValue (int numValue) {
	if (isClear) isClear = false;
	this.numValue = numValue;
    }
    public boolean isNumValueSet() {
	return (Double.isNaN(numValue))? false: true;
    }
    /*public boolean isEqualNumValue(String numValue) {
	return (this.numValue == numValue)? true: false;
    }*/
    public double getMinValue () {
	return minValue;
    }
    void setMinValue (int minValue) {
	if (isClear) isClear = false;
	this.minValue = minValue;
    }
    public boolean isMinValueSet() {
	return (Double.isNaN(minValue))? false: true;
    }
    /*public boolean isEqualMinValue(int minValue) {
	return (this.minValue == minValue)? true: false;
    }*/
    public double getMaxValue () {
	return maxValue;
    }
    void setMaxValue (int maxValue) {
	if (isClear) isClear = false;
	this.maxValue = maxValue;
    }
    public boolean isMaxValueSet() {
	return (Double.isNaN(maxValue))? false: true;
    }
    /*public boolean isEqualMaxValue(int maxValue) {
	return (this.maxValue == maxValue)? true: false;
    }*/
    public int getLength () {
	return length;
    }
    void setLength (int length) {
	if (isClear) isClear = false;
	this.length = length;
    }
    public boolean isLengthSet() {
	return (length < 0)? false: true;
    }
    /*public boolean isEqualLength(int length) {
	return (this.length == length)? true: false;
    }*/
    public int getMinLength () {
	return minLength;
    }
    void setMinLength (int minLength) {
	if (isClear) isClear = false;
	this.minLength = minLength;
    }
    public boolean isMinLengthSet() {
	return (minLength < 0)? false: true;
    }
    /*public boolean isEqualMinLength(int minLength) {
	return (this.minLength == minLength)? true: false;
    }*/
    public int getMaxLength () {
	return maxLength;
    }
    void setMaxLength (int maxLength) {
	if (isClear) isClear = false;
	this.maxLength = maxLength;
    }
    public boolean isMaxLengthSet() {
	return (maxLength < 0)? false: true;
    }
    /*public boolean isEqualMaxLength(int maxLength) {
	return (this.maxLength == maxLength)? true: false;
    }*/
    public String getStartsWith () {
	return startsWith;
    }
    void setStartsWith (String startsWith) {
	if (isClear) isClear = false;
	this.startsWith = startsWith;
    }
    public boolean isStartsWithSet() {
	return (startsWith == null)? false: true;
    }
    /*public boolean isEqualStartsWith(String startsWith) {
	return (startsWith.equals(this.startsWith))? true: false;
    }*/
    String getEndsWith () {
	return endsWith;
    }
    void setEndsWith (String endsWith) {
	if (isClear) isClear = false;
	this.endsWith = endsWith;
    }
    public boolean isEndsWithSet() {
	return (endsWith == null)? false: true;
    }
    /*public boolean isEqualEndsWith(String endsWith) {
	return (endsWith.equals(this.endsWith))? true: false;
    }*/
    String getContaints () {
	return containts;
    }
    void setContaints (String containts) {
	if (isClear) isClear = false;
	this.containts = containts;
    }
    public boolean isContaintsSet() {
	return (containts == null)? false: true;
    }
    /*public boolean isEqualContaints(String containts) {
	return (containts.equals(this.containts))? true: false;
    }*/
    public String toString() {
	return ( (isClear)? "Concept is clear\n": "Concept isn't clear\n")
		+ ((typeInfo == null)? "": "ConceptType = "+typeInfo.name+"; ")
		+ ((groupNum < 0)? "": "groupNum = "+groupNum+"; ")
		+ ( (value == null)? "": VALUE+" = "+value+"; " )
		+ ( (Double.isNaN(numValue))? "": NUM_VALUE+" = "+numValue+"; " )
		+ ( (Double.isNaN(minValue))? "": MIN_VALUE+" = "+minValue+"; " )
		+ ( (Double.isNaN(maxValue))? "": MAX_VALUE+" = "+maxValue+"; " )
		+ ( (length < 0)? "": LENGTH+" = "+length+"; " )
		+ ( (minLength < 0)? "": MIN_LENGTH+" = "+minLength+"; " )
		+ ( (maxLength < 0)? "": MAX_LENGTH+" = "+maxLength+"; " )
		+ ( (startsWith == null)? "": STARTS_WITH+" = "+startsWith+"; " )
		+ ( (endsWith == null)? "": ENDS_WITH+" = "+endsWith+"; " )
		+ ( (containts == null)? "": CONTAINS+" = "+containts)
		+'\n';
    }
  
}
